package jwcb.hire.common.security.annotation;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

public class ValueInValidator implements ConstraintValidator<ValueIn, Object> {

    private ValueIn constraint;
    private Set<Object> validValues = new HashSet<>();
    private Class<?> valueType;
    private Method getValueMethod;

    @Override
    public void initialize(ValueIn constraint) {
        this.constraint = constraint;
        Class<? extends Enum<?>> enumClass = constraint.enumClass();
        // 获取枚举值
        Enum<?>[] enumConstants = enumClass.getEnumConstants();
        if (enumConstants == null || enumConstants.length == 0) {
            throw new IllegalArgumentException("枚举类 " + enumClass.getName() + " 不包含任何值");
        }

        try {
            // 强制要求必须存在 getValue() 方法
            this.getValueMethod = enumClass.getMethod("getValue");
            this.valueType = getValueMethod.getReturnType();

            // 收集所有有效的 value 值
            for (Enum<?> e : enumConstants) {
                Object value = getValueMethod.invoke(e);
                validValues.add(value);

            }
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("枚举类 " + enumClass.getName() + " 必须包含 getValue() 方法", e);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException("无法访问枚举的 getValue() 方法", e);
        }
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        if(value.getClass() != valueType){
            return false;
        }
        return validValues.contains(value);
    }

}